package com.iwhalecloud.bss.kite.cucc.order.accept.chain.impl;

import com.iwhalecloud.bss.kite.client.dto.cust.CustDTO;
import com.iwhalecloud.bss.kite.client.dto.shoppingcart.ShoppingCartGroupInstDTO;
import com.iwhalecloud.bss.kite.common.constant.KeyConsts;
import com.iwhalecloud.bss.kite.common.constant.ServiceOfferConsts;
import com.iwhalecloud.bss.kite.common.constant.TableConsts;
import com.iwhalecloud.bss.kite.common.util.KiteBeanUtils;
import com.iwhalecloud.bss.kite.common.util.KiteListUtils;
import com.iwhalecloud.bss.kite.common.util.KiteMapUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.common.util.TransactionUtils;
import com.iwhalecloud.bss.kite.cucc.order.accept.chain.AbstractOrderHandler;
import com.iwhalecloud.bss.kite.cucc.order.util.OrderRelUtil;
import com.iwhalecloud.bss.kite.dataservice.cache.DcPublicCache;
import com.iwhalecloud.bss.kite.dataservice.entity.CustomerOrder;
import com.iwhalecloud.bss.kite.dataservice.entity.KiteAttrConfig;
import com.iwhalecloud.bss.kite.dataservice.entity.OrderAttr;
import com.iwhalecloud.bss.kite.dataservice.mapper.order.CustomerOrderMapper;
import com.iwhalecloud.bss.kite.dataservice.mapper.order.OrderAttrMapper;
import com.iwhalecloud.bss.kite.dataservice.util.IdUtils;
import com.iwhalecloud.bss.kite.manager.api.IQuerySceneInstService;
import com.iwhalecloud.bss.kite.manager.enums.ActionType;
import com.iwhalecloud.bss.kite.manager.inst.KiteAttr;
import com.iwhalecloud.bss.kite.manager.inst.KiteOrderItemAttr;
import com.iwhalecloud.bss.kite.order.client.context.OrderContext;
import com.iwhalecloud.bss.kite.order.client.dto.OrderContainer;
import com.iwhalecloud.bss.kite.order.client.dto.OrderRequest;
import com.ztesoft.bss.base.staticdata.CoreDataInteract;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <Description> <br>
 * 订单受理流程：客户订单处理
 *
 * @author xiao.xuzhang<br>
 * @version 1.0<br>
 * @taskId <br>
 * @CreateDate 2020年2月12日 <br>
 * @since R9.0<br>
 * @see com.iwhalecloud.bss.kite.cucc.order.accept.chain.impl <br>
 */
@Component
public class CustomerOrderHandler extends AbstractOrderHandler {

    @Resource
    private IQuerySceneInstService querySceneInstService;

    @Resource
    private CustomerOrderMapper customerOrderMapper;

    @Resource
    private OrderAttrMapper orderAttrMapper;

    @Override
    public void doHandle(OrderRequest orderRequest) {
        OrderContainer orderContainer = orderRequest.getOrderContainer();
        CustomerOrder customerOrder = orderContainer.getCustomerOrder();
        //更新客户订单
        CustomerOrder custOrder = upadteCustomerOrder(customerOrder);

        List<ShoppingCartGroupInstDTO> groupInsts = orderRequest.getGroupInstContainer().getShoppingCartGroupInsts().stream()
            .filter(t -> orderRequest.getMainSceneInstId().equals(t.getGroupId())).collect(Collectors.toList());
        if (KeyConsts.KITE_SCENE_INST_OPER_TYPE_1001.equals(groupInsts.get(0).getOperType())) {
            custOrder.setOperType(CoreDataInteract.EVT_C_0011_1100);
        }

        //更新客户订单属性
        updateOrderAttrByCustOrderId(custOrder.getCustOrderId());
    }


    /**
     * 查询当前客户订单
     *
     * @param custOrderId
     * @return
     */
    public CustomerOrder getAllByCustOrderId(String custOrderId, String custId) {
        Example example = new Example(CustomerOrder.class);
        example.createCriteria().andEqualTo("custOrderId", custOrderId).andEqualTo("custId", custId);
        return customerOrderMapper.selectOneByExample(example);
    }

    /**
     * 更新当前客户订单
     */
    public CustomerOrder upadteCustomerOrder(CustomerOrder customerOrder) {
        CustomerOrder  newCustOrder = new CustomerOrder();
        if (null != customerOrder) {
            if (ActionType.M.name().equals(customerOrder.getActionType())) {
                OrderContext.getOrderRequest().getOrderContainer().setCustomerOrder(customerOrder);
                newCustOrder = KiteBeanUtils.transform(customerOrder, CustomerOrder.class);
            }
            else if (ActionType.A.name().equals(customerOrder.getActionType())) {
                //不存在 则创建新的客户订单
                OrderRequest orderRequest = OrderContext.getOrderRequest();
                newCustOrder = createNewCustOrder(orderRequest, customerOrder);
            }

        }
        else {
            //不存在 则创建新的客户订单
            OrderRequest orderRequest = OrderContext.getOrderRequest();
            newCustOrder =  createNewCustOrder(orderRequest, null);

        }
        String serviceOfferId = OrderContext.getOrderRequest().getServiceOfferId();
        if (ServiceOfferConsts.SERVICE_OFFER_TRANSFER.equals(serviceOfferId) || ServiceOfferConsts.SERVICE_OFFER_CUST_RETURN.equals(
            serviceOfferId)) {
            newCustOrder.setNewCustId(OrderContext.getOrderRequest().getNewCustId());
        }
        return newCustOrder;
    }


    public CustomerOrder createNewCustOrder(OrderRequest orderRequest, CustomerOrder custOrder) {
        String custOrderId = orderRequest.getCustOrderId();
        String custId = orderRequest.getCustId();
        String extCustOrderId = "";
        String operType = "";
        if (custOrder != null) {
            extCustOrderId = custOrder.getExtCustOrderId();
            operType = custOrder.getOperType();
        }

        String newCustId = orderRequest.getNewCustId();
        String postId = orderRequest.getPostId();
        String orgId = orderRequest.getOrgId();
        String lanId = orderRequest.getLanId();
        String regionId = orderRequest.getRegionId();
        String staffId = orderRequest.getStaffId();
        CustDTO cust = OrderContext.getCust();
        //处理客户订单属性回填上下文
        if (!StringUtils.isEmpty(custOrderId)) {
            CustomerOrder order = this.getAllByCustOrderId(custOrderId, custId);
            if (!Objects.isNull(order)) {
                order.setActionType(ActionType.K.name());
                OrderContext.getOrderRequest().getOrderContainer().setCustomerOrder(order);
                return order;
            }
        }
        // 数据库不存在，创建新的客户订单
        CustomerOrder customerOrder = new CustomerOrder();
        if (StringUtils.isEmpty(custOrderId)) {
            custOrderId = IdUtils.genCustOrderId(lanId);
        }
        customerOrder.setCustOrderId(custOrderId);
        customerOrder.setCustId(custId);
        //如果是过户或客户归档撤单，客户标识取新客户标识
        if (KeyConsts.KITE_SCENE_INST_OPER_TYPE_1002.equals(operType)) {
            String serviceOfferId = OrderContext.getOrderRequest().getServiceOfferId();
            if (ServiceOfferConsts.SERVICE_OFFER_TRANSFER.equals(serviceOfferId)
                || ServiceOfferConsts.SERVICE_OFFER_CUST_RETURN.equals(serviceOfferId)) {
                customerOrder.setCustId(newCustId);
            }
        }
        customerOrder.setCustOrderNo(custOrderId);
        customerOrder.setCustOrderNbr(custOrderId);
        customerOrder.setCustName(cust.getCustName());
        customerOrder.setAcceptDate(LocalDateTime.now());
        customerOrder.setAcceptLanId(lanId);
        customerOrder.setAcceptRegionId(regionId);
        customerOrder.setCreateDate(LocalDateTime.now());
        customerOrder.setCreateOrgId(orgId);
        customerOrder.setCreatePost(postId);
        customerOrder.setCreateStaff(staffId);
        customerOrder.setUpdateStaff(staffId);
        customerOrder.setUpdateOrg(orgId);
        customerOrder.setUpdatePost(postId);
        customerOrder.setCustOrderType(KeyConsts.CUST_ORDER_TYPE_EVT_C_0012_1100);
        customerOrder.setLanId(lanId);
        /**
         * 操作类型<br>
         * 1000: 正常, 1001: 修正, 1002: 撤单
         */
        if (KiteStringUtils.isEmpty(operType)) {
            operType = CoreDataInteract.EVT_C_0011_1000;
        }
        customerOrder.setOperType(operType);
        if (KiteStringUtils.isNotEmpty(extCustOrderId)) {
            customerOrder.setExtCustOrderId(extCustOrderId);
        }
        String askSource = KeyConsts.ORDER_SOURCE_EVT_C_0001_1401;
        if (KiteStringUtils.isNotEmpty(askSource)) {
            askSource = orderRequest.getAskSource();
        }
        customerOrder.setOrderSource(askSource);
        customerOrder.setRegionId(regionId);
        List<String> sceneInstIds = orderRequest.getSceneInstIds();
        List<KiteAttr> commonAttrs = new ArrayList<>();
        if (KiteListUtils.isNotEmpty(sceneInstIds)) {
            for (String sceneInstId : sceneInstIds) {
                commonAttrs.addAll(querySceneInstService.listCommonAttrs(sceneInstId));
            }
        }
        for (KiteAttr commonAttr : commonAttrs) {
            if ("remark".equals(commonAttr.getFieldName())) {
                customerOrder.setRemark(commonAttr.getValue());
                break;
            }
        }
        customerOrder.setStaffId(staffId);
        customerOrder.setStatusCd(CoreDataInteract.EVT_0002_100000); // 受理中
        customerOrder.setStatusDate(LocalDateTime.now());
        customerOrder.setVerNum("0");
        customerOrder.setSysSource("-1");
        customerOrder.setActionType(ActionType.A.name());
        // 使用独立事务创建客户订单
        TransactionUtils.executeNew(() -> customerOrderMapper.insert(customerOrder));
        //将客户信息存入容器中
        OrderContext.getOrderRequest().getOrderContainer().setCustomerOrder(customerOrder);

        return customerOrder;
    }


    /**
     * 查询所有客户订单属性列表
     *
     * @param custOrderId
     * @return
     */
    public List<OrderAttr> getAllOrderAttrByCustOrderId(String custOrderId) {
        Example example = new Example(CustomerOrder.class);
        example.createCriteria().andEqualTo("custOrderId", custOrderId);
        return orderAttrMapper.selectByExample(example);
    }

    /**
     * 更新所有客户订单属性
     *
     * @param custOrderId
     * @return
     */
    public void updateOrderAttrByCustOrderId(String custOrderId) {
        //更新订单属性客户或者值。
        OrderRequest orderRequest = OrderContext.getOrderRequest();
        OrderContainer orderContainer = orderRequest.getOrderContainer();
        Map<String, List<OrderAttr>> orderAttrMap = orderContainer.getOrderAttrMap();
        List<OrderAttr> assemblyAttrs = new ArrayList<>();
        if (KiteMapUtils.isEmpty(orderAttrMap)) {
            Map<String, List<OrderAttr>> newOrderAttrMap = new HashMap<String, List<OrderAttr>>();
            List<OrderAttr> alOrderAttrs = getAllOrderAttrByCustOrderId(custOrderId);
            if (!KiteListUtils.isEmpty(alOrderAttrs)) {
                alOrderAttrs.forEach(t -> {
                    t.setActionType(KeyConsts.ACTION_TYPE_K);
                    assemblyAttrs.add(t);
                });
            }

            //拼装客户订单新属性，排除存在的客户订单属性
            assemblyAttrs.addAll(createOrderAttrs(assemblyAttrs));

            //设置新流程标识
            KiteAttr kiteFlagNew = new KiteAttr();
            kiteFlagNew.setFieldName("newFlowFlag");
            kiteFlagNew.setValue("Y");
            kiteFlagNew.setAttrId("-1");
            assemblyAttrs.add(addOrderAttr(kiteFlagNew));

            // 设置一人一码标识
            setOnePersonOneYardFlag(assemblyAttrs, orderRequest);

            if (!KiteListUtils.isEmpty(assemblyAttrs)) {
                newOrderAttrMap.put(custOrderId, assemblyAttrs);
                orderContainer.setOrderAttrMap(newOrderAttrMap);
            }
        }
    }

    private List<OrderAttr>  createOrderAttrs(List<OrderAttr> existAttrs) {
        List<String> sceneInstIds = OrderContext.getOrderRequest().getSceneInstIds();
        List<KiteAttr> kiteAttrs = new ArrayList<>();
        List<OrderAttr> assemblyAttrs = new ArrayList<>();
        if (KiteListUtils.isNotEmpty(sceneInstIds)) {
            for (String sceneInstId : sceneInstIds) {
                kiteAttrs.addAll(querySceneInstService.listCommonAttrs(sceneInstId));
            }
        }
        OrderRequest orderRequest = OrderContext.getOrderRequest();
        String serviceOfferId = orderRequest.getServiceOfferId();
        loop: for (KiteAttr attr : kiteAttrs) {
            if (KiteStringUtils.isEmpty(attr.getValue())) {
                continue;
            }

            for (OrderAttr existAttr : existAttrs) {
                if (existAttr.getFieldName().equals(attr.getFieldName())) {
                    break loop;
                }
            }

            KiteAttrConfig existConfig = OrderRelUtil.isExistTable(attr.getFieldName(), serviceOfferId, TableConsts.OrderAttr.getTableName());
            if (null != existConfig) {
                assemblyAttrs.add(addOrderAttr(attr));
            }
        }

       return assemblyAttrs;
    }

    private OrderAttr addOrderAttr(KiteAttr attr) {
        // 根据fieldName查询kite_attr_config数据，table_name为order_attr入库
        OrderAttr orderAttr = new OrderAttr();
        OrderRequest orderRequest = OrderContext.getOrderRequest();
        String staffId = orderRequest.getStaffId();
        String custId = orderRequest.getCustId();
        String fieldName = attr.getFieldName();
        String custOrderId = orderRequest.getCustOrderId();

        //创建客户订单属性
        orderAttr.setpFieldName(fieldName);
        orderAttr.setOrderAttrId(IdUtils.getSeqOrderAttrId());
        String curAttrId = attr.getAttrId();
        orderAttr.setpOrderAttrId("");
        if (StringUtils.isBlank(curAttrId)) {
            curAttrId = "-1";
        }
        orderAttr.setAttrId(curAttrId);
        orderAttr.setpOrderAttrId("-1");
        orderAttr.setAttrValueId("-1");
        orderAttr.setVerNum("-1");
        orderAttr.setOperType(CoreDataInteract.EVT_C_0011_1000);
        orderAttr.setStatusCd(CoreDataInteract.EVT_C_0014_1100);
        orderAttr.setStatusDate(new Date());
        orderAttr.setCreateStaff(staffId);
        orderAttr.setCreateDate(new Date());
        orderAttr.setUpdateDate(new Date());
        orderAttr.setCustOrderId(custOrderId);
        orderAttr.setFieldName(fieldName);
        orderAttr.setAttrValue(attr.getValue());
        orderAttr.setOrderType("000");
        orderAttr.setCustId(custId);
        orderAttr.setUpdateStaff(staffId);
        orderAttr.setActionType(KeyConsts.ACTION_TYPE_A);
        //过户和客户归并设置新的客户id，进行更新
        String serviceOfferId = OrderContext.getOrderRequest().getServiceOfferId();
        if (ServiceOfferConsts.SERVICE_OFFER_TRANSFER.equals(serviceOfferId) || ServiceOfferConsts.SERVICE_OFFER_CUST_RETURN.equals(
            serviceOfferId)) {
            orderAttr.setNewCustId(orderRequest.getNewCustId());
        }
        return orderAttr;
    }

    private void setOnePersonOneYardFlag(List<OrderAttr> assemblyAttrs, OrderRequest orderRequest) {
        // 一人一码标识打标时把值set到了OrderItemAttr，写order_attr表时需要从OrderItemAttr中取值
        Map<String, List<KiteOrderItemAttr>> kiteOrderItemAttrMap = orderRequest.getSceneInstIds().stream()
            .flatMap(t -> querySceneInstService.listOrderItemAttrs(t).stream())
            .collect(Collectors.groupingBy(t -> t.getFieldName()));

        String codea = DcPublicCache.getCodea("2020022701", "one_person_one_code");
        for (String key : kiteOrderItemAttrMap.keySet()) {
            if (KiteStringUtils.contains(codea, key)) {
                List<KiteOrderItemAttr> KiteOrderItemAttrList = (List<KiteOrderItemAttr>) KiteMapUtils.getObject(kiteOrderItemAttrMap, key);
                // 同一个客户订单项，order_item_attr因为实例类型不同，可能有多个一人一码标识，但值是一样的，写order_attr表只需取一条即可
                KiteOrderItemAttr kiteOrderItemAttr = KiteOrderItemAttrList.get(0);
                if (Objects.isNull(kiteOrderItemAttr) && KiteStringUtils.isNotEmpty(kiteOrderItemAttr.getAttrValue())) {
                    continue;
                }
                KiteAttr kiteAttr = new KiteAttr();
                kiteAttr.setFieldName(kiteOrderItemAttr.getFieldName());
                kiteAttr.setValue(kiteOrderItemAttr.getAttrValue());
                kiteAttr.setAttrId(kiteOrderItemAttr.getAttrId());
                assemblyAttrs.add(addOrderAttr(kiteAttr));
            }
        }
    }

}
